package com.ssf.infrastructure.persistent.repository;

import cn.hutool.core.bean.BeanUtil;
import com.ssf.domain.strategy.model.entity.StrategyAwardEntity;
import com.ssf.domain.strategy.model.entity.StrategyRuleEntity;
import com.ssf.domain.strategy.repository.IStrategyRepository;
import com.ssf.infrastructure.persistent.dao.StrategyAwardDao;
import com.ssf.infrastructure.persistent.dao.StrategyRuleDao;
import com.ssf.infrastructure.persistent.po.StrategyAward;
import com.ssf.infrastructure.persistent.po.StrategyRule;
import com.ssf.infrastructure.persistent.redis.IRedisService;
import com.ssf.types.common.Constants;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMap;
import org.redisson.misc.Hash;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Repository
@Slf4j
public class StrategyRepository implements IStrategyRepository {
    @Resource
    private IRedisService redisService;
    @Resource
    private StrategyAwardDao strategyAwardDao;
    @Resource
    private StrategyRuleDao strategyRuleDao;
    @Override
    public List<StrategyAwardEntity> getStrategyAwardEntityByStrategyId(Long strategyId) {
        //先从缓存中获取
        String redisKey = Constants.RedisKey.STRATEGY_AWARD_KEY + "_" + strategyId;
        List<StrategyAwardEntity> strategyAwardEntities = redisService.getValue(redisKey);
        if(strategyAwardEntities!=null&&!strategyAwardEntities.isEmpty()) {//缓存存在，直接返回
            return strategyAwardEntities;
        }
        //缓存获取失败，通过Dao获取，并将获取到的数据保存到缓存中
        List<StrategyAward> strategyAwards=strategyAwardDao.queryStrategyAwardListByStrategyId(strategyId);
        log.info("strategyAwards:{}",strategyAwards);
        strategyAwardEntities = BeanUtil.copyToList(strategyAwards, StrategyAwardEntity.class);
        redisService.setValue(redisKey,strategyAwardEntities);
        return strategyAwardEntities;
    }

    @Override
    public void restoreLotteryMap(String key, int lotteryRange, HashMap<Integer, Integer> map) {
        //保存策略对应的抽奖范围
        redisService.setValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY+"_"+key,lotteryRange);
        //保存策略对应的抽奖map
        redisService.getMap(Constants.RedisKey.STRATEGY_RATE_TABLE_KEY+"_"+key).putAll(map);//将map中的条目全部加到RMap中
    }

    @Override
    public int getLotteryRange(String key) {
        return redisService.getValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + "_" + key);
    }

    @Override
    public HashMap<Integer, Integer> getLotteryMap(String key) {
        RMap<Object, Object> map = redisService.getMap(Constants.RedisKey.STRATEGY_RATE_TABLE_KEY + "_" + key);
        HashMap<Integer,Integer> result=new HashMap<>();
        for (Map.Entry<Object, Object> entry : map.entrySet()) {
            result.put((int)entry.getKey(),(int)entry.getValue());
        }
        return result;
    }

    @Override
    public List<StrategyRuleEntity> getStrategyRuleEntityByStrategyId(Long strategyId) {
        String redisKey=Constants.RedisKey.STRATEGY_RULE_KEY+"_"+strategyId;
        List<StrategyRuleEntity> strategyRuleEntities=redisService.getValue(redisKey);
        if(strategyRuleEntities!=null&&!strategyRuleEntities.isEmpty()) {
            return strategyRuleEntities;
        }
        List<StrategyRule> strategyRules = strategyRuleDao.getStrategyRuleByStrategyId(strategyId);
        strategyRuleEntities = BeanUtil.copyToList(strategyRules, StrategyRuleEntity.class);
        redisService.setValue(redisKey,strategyRuleEntities);
        return strategyRuleEntities;
    }

    @Override
    public List<StrategyAwardEntity> getStrategyAwardEntityByStrategyIdAndAwardId(Long strategyId, List<Integer> awardId) {
        //先获取策略对应奖品实体，这个过程会操作缓存
        List<StrategyAwardEntity> strategyAwardEntities = getStrategyAwardEntityByStrategyId(strategyId);
        //从中筛选出需要的
        if(strategyAwardEntities!=null&&!strategyAwardEntities.isEmpty()) {//缓存命中，筛选出在awardId这个List中存在的，组成新的列表返回
            HashSet<Integer> set=new HashSet<>(awardId);
            return strategyAwardEntities.stream().filter(strategyAwardEntity -> set.contains(strategyAwardEntity.getAwardId())).collect(Collectors.toList());
        } else {
            return null;
        }

    }
}
